<?php

namespace App\Constants;

use App\Constants\AbstractEnum;

/**
 * 上传状态枚举
 * 定义文件上传过程中的各种状态
 */
class UploadStatusEnum extends AbstractEnum
{
    // 上传状态常量
    public const PENDING = 'pending';         // 等待上传
    public const UPLOADING = 'uploading';     // 上传中
    public const VALIDATING = 'validating';   // 验证中
    public const PROCESSING = 'processing';   // 处理中
    public const COMPLETED = 'completed';     // 完成
    public const FAILED = 'failed';           // 失败
    public const CANCELLED = 'cancelled';     // 已取消
    public const RETRYING = 'retrying';       // 重试中

    /**
     * 获取上传状态标签
     */
    public static function getLabels(): array
    {
        return [
            self::PENDING => '等待上传',
            self::UPLOADING => '上传中',
            self::VALIDATING => '验证中',
            self::PROCESSING => '处理中',
            self::COMPLETED => '完成',
            self::FAILED => '失败',
            self::CANCELLED => '已取消',
            self::RETRYING => '重试中',
        ];
    }

    /**
     * 获取上传状态颜色
     */
    public static function getColors(): array
    {
        return [
            self::PENDING => '#6C757D',       // 灰色
            self::UPLOADING => '#17A2B8',     // 青色
            self::VALIDATING => '#FFC107',    // 黄色
            self::PROCESSING => '#FFC107',    // 黄色
            self::COMPLETED => '#28A745',     // 绿色
            self::FAILED => '#DC3545',        // 红色
            self::CANCELLED => '#6C757D',     // 灰色
            self::RETRYING => '#FFC107',      // 黄色
        ];
    }

    /**
     * 获取上传状态图标
     */
    public static function getIcons(): array
    {
        return [
            self::PENDING => 'clock',
            self::UPLOADING => 'upload',
            self::VALIDATING => 'search',
            self::PROCESSING => 'cog',
            self::COMPLETED => 'check-circle',
            self::FAILED => 'times-circle',
            self::CANCELLED => 'ban',
            self::RETRYING => 'redo',
        ];
    }

    /**
     * 检查状态是否为活跃状态
     */
    public static function isActive(string $status): bool
    {
        return in_array($status, [self::UPLOADING, self::VALIDATING, self::PROCESSING, self::RETRYING]);
    }

    /**
     * 检查状态是否为完成状态
     */
    public static function isCompleted(string $status): bool
    {
        return $status === self::COMPLETED;
    }

    /**
     * 检查状态是否为失败状态
     */
    public static function isFailed(string $status): bool
    {
        return in_array($status, [self::FAILED, self::CANCELLED]);
    }

    /**
     * 检查状态是否为可重试状态
     */
    public static function isRetryable(string $status): bool
    {
        return in_array($status, [self::FAILED, self::CANCELLED]);
    }

    /**
     * 获取可用的状态转换
     */
    public static function getAvailableTransitions(string $currentStatus): array
    {
        $transitions = [
            self::PENDING => [self::UPLOADING, self::CANCELLED],
            self::UPLOADING => [self::VALIDATING, self::FAILED, self::CANCELLED],
            self::VALIDATING => [self::PROCESSING, self::COMPLETED, self::FAILED],
            self::PROCESSING => [self::COMPLETED, self::FAILED],
            self::COMPLETED => [], // 完成状态不可逆转
            self::FAILED => [self::RETRYING, self::CANCELLED], // 可重试或取消
            self::CANCELLED => [], // 取消状态不可逆转
            self::RETRYING => [self::UPLOADING, self::FAILED, self::CANCELLED],
        ];

        return $transitions[$currentStatus] ?? [];
    }

    /**
     * 检查状态转换是否有效
     */
    public static function isValidTransition(string $fromStatus, string $toStatus): bool
    {
        $availableTransitions = self::getAvailableTransitions($fromStatus);
        return in_array($toStatus, $availableTransitions);
    }

    /**
     * 获取状态的进度百分比
     */
    public static function getProgressPercentage(string $status): int
    {
        $progressMap = [
            self::PENDING => 0,
            self::UPLOADING => 25,
            self::VALIDATING => 50,
            self::PROCESSING => 75,
            self::COMPLETED => 100,
            self::FAILED => 0,
            self::CANCELLED => 0,
            self::RETRYING => 10,
        ];

        return $progressMap[$status] ?? 0;
    }

    /**
     * 获取状态的优先级（用于排序）
     */
    public static function getPriority(string $status): int
    {
        $priorities = [
            self::FAILED => 1,      // 失败优先级最高
            self::UPLOADING => 2,   // 上传中次之
            self::RETRYING => 3,    // 重试中
            self::VALIDATING => 4,  // 验证中
            self::PROCESSING => 5,  // 处理中
            self::PENDING => 6,     // 等待中
            self::COMPLETED => 7,   // 完成
            self::CANCELLED => 8,   // 取消优先级最低
        ];

        return $priorities[$status] ?? 99;
    }

    /**
     * 获取状态的超时时间（秒）
     */
    public static function getTimeoutSeconds(string $status): int
    {
        $timeouts = [
            self::UPLOADING => 3600,   // 1小时
            self::VALIDATING => 300,   // 5分钟
            self::PROCESSING => 1800,  // 30分钟
            self::RETRYING => 300,     // 5分钟
        ];

        return $timeouts[$status] ?? 300; // 默认5分钟
    }

    /**
     * 获取状态的描述信息
     */
    public static function getStatusDescription(string $status): string
    {
        $descriptions = [
            self::PENDING => '文件正在等待上传',
            self::UPLOADING => '文件正在上传到服务器',
            self::VALIDATING => '正在验证文件格式和内容',
            self::PROCESSING => '正在处理和转换文件',
            self::COMPLETED => '文件上传和处理已完成',
            self::FAILED => '文件上传或处理过程中出现错误',
            self::CANCELLED => '文件上传已被用户取消',
            self::RETRYING => '正在重新尝试上传文件',
        ];

        return $descriptions[$status] ?? '未知状态';
    }

    /**
     * 获取状态的用户友好提示
     */
    public static function getUserMessage(string $status): string
    {
        $messages = [
            self::PENDING => '准备上传文件，请稍候...',
            self::UPLOADING => '正在上传文件，请勿关闭页面...',
            self::VALIDATING => '正在验证文件，请稍候...',
            self::PROCESSING => '正在处理文件，请稍候...',
            self::COMPLETED => '文件上传成功！',
            self::FAILED => '文件上传失败，请检查文件格式或网络连接后重试',
            self::CANCELLED => '文件上传已取消',
            self::RETRYING => '正在重新上传文件...',
        ];

        return $messages[$status] ?? '未知状态';
    }

    /**
     * 检查状态是否需要用户干预
     */
    public static function requiresUserAction(string $status): bool
    {
        return in_array($status, [self::FAILED, self::CANCELLED]);
    }

    /**
     * 获取状态的下一检查时间间隔（秒）
     */
    public static function getNextCheckInterval(string $status): int
    {
        $intervals = [
            self::PENDING => 5,       // 5秒
            self::UPLOADING => 2,     // 2秒
            self::VALIDATING => 3,    // 3秒
            self::PROCESSING => 5,    // 5秒
            self::RETRYING => 10,     // 10秒
            self::COMPLETED => 0,     // 不需要检查
            self::FAILED => 0,        // 不需要检查
            self::CANCELLED => 0,     // 不需要检查
        ];

        return $intervals[$status] ?? 5; // 默认5秒
    }

    /**
     * 获取状态的最大重试次数
     */
    public static function getMaxRetryCount(string $status): int
    {
        $retryCounts = [
            self::UPLOADING => 3,     // 上传失败最多重试3次
            self::VALIDATING => 1,    // 验证失败最多重试1次
            self::PROCESSING => 2,    // 处理失败最多重试2次
        ];

        return $retryCounts[$status] ?? 0; // 默认不重试
    }

    /**
     * 检查是否可以取消操作
     */
    public static function canCancel(string $status): bool
    {
        return in_array($status, [self::PENDING, self::UPLOADING, self::VALIDATING, self::PROCESSING, self::RETRYING]);
    }

    /**
     * 获取状态的CSS类名（用于前端样式）
     */
    public static function getCssClass(string $status): string
    {
        $cssClasses = [
            self::PENDING => 'status-pending',
            self::UPLOADING => 'status-uploading',
            self::VALIDATING => 'status-validating',
            self::PROCESSING => 'status-processing',
            self::COMPLETED => 'status-completed',
            self::FAILED => 'status-failed',
            self::CANCELLED => 'status-cancelled',
            self::RETRYING => 'status-retrying',
        ];

        return $cssClasses[$status] ?? 'status-unknown';
    }
}
